<!DOCTYPE html>

<html lang="en" data-content_root="../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Integration with Google Drive &#8212; Pytch  documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=03e43079" />
    <link rel="stylesheet" type="text/css" href="../../_static/classic.css?v=36340f97" />
    <link rel="stylesheet" type="text/css" href="../../_static/css/pytch-classic.css?v=0321735e" />
    
    <script src="../../_static/documentation_options.js?v=7f41d439"></script>
    <script src="../../_static/doctools.js?v=9bcbadda"></script>
    <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
    
    <link rel="icon" href="../../_static/favicon.ico"/>
    <link rel="author" title="About these documents" href="../../about.html" />
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="Media Library" href="assets-library.html" />
    <link rel="prev" title="Project storage as zipfile" href="zipfile-format.html" /> 
  </head><body>
<div class="NavBar">
  <a href="../../../app/"><h1>Pytch</h1></a>
  <ul>
    <a href="https://pytch.scss.tcd.ie/"><li>About Pytch</li></a>
    <a href="../../index.html"><li>Help</li></a>
    <a href="../../../app/tutorials/"><li>Tutorials</li></a>
    <a href="../../../app/my-projects/"><li>My projects</li></a>
  </ul>
</div>
<div class="warning-work-in-progress">
  <p>These help pages are incomplete — we are working on it!</p>
</div>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="integration-with-google-drive">
<h1>Integration with Google Drive<a class="headerlink" href="#integration-with-google-drive" title="Link to this heading">¶</a></h1>
<p>Pytch can save (“export”) projects to, and load (“import”) projects
from, Google Drive.  This section summarises the design and
implementation of this feature.</p>
<section id="whats-stored">
<h2>What’s stored<a class="headerlink" href="#whats-stored" title="Link to this heading">¶</a></h2>
<p>Export/import uses <a class="reference internal" href="zipfile-format.html#storage-as-zipfile"><span class="std std-ref">the same zipfile format</span></a>
as “download” / “upload”.  When exporting, the filename is
automatically generated along the lines of</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">My</span> <span class="pre">cool</span> <span class="pre">project</span> <span class="pre">(exported</span> <span class="pre">20230516T160905).zip</span></code></p></li>
</ul>
</section>
<section id="api-objects">
<h2>API objects<a class="headerlink" href="#api-objects" title="Link to this heading">¶</a></h2>
<p>Google Drive operations are provided through API objects, to allow
Cypress-based testing of the UI flows under different error
conditions.</p>
<p>The real Google API has a set-up phase where Google-provided scripts
are loaded.  There is therefore a <em>boot</em> process which returns an
object capable of performing the Google Drive operations.  (Or throws
an exception if something goes wrong.)</p>
<section id="google-drive-boot-api">
<h3>Google Drive Boot API<a class="headerlink" href="#google-drive-boot-api" title="Link to this heading">¶</a></h3>
<p>Provides just the method <code class="docutils literal notranslate"><span class="pre">boot()</span></code>, returning an object providing the
following API:</p>
</section>
<section id="google-drive-api">
<h3>Google Drive API<a class="headerlink" href="#google-drive-api" title="Link to this heading">¶</a></h3>
<p>Provides <code class="docutils literal notranslate"><span class="pre">acquireToken()</span></code>, <code class="docutils literal notranslate"><span class="pre">getUserInfo()</span></code>, <code class="docutils literal notranslate"><span class="pre">importFiles()</span></code> and
<code class="docutils literal notranslate"><span class="pre">exportFile()</span></code> methods.  See docstrings in the code for details.</p>
</section>
</section>
<section id="authentication-flow">
<h2>Authentication flow<a class="headerlink" href="#authentication-flow" title="Link to this heading">¶</a></h2>
<p>There is an authentication and consent flow, mostly handled by
Google-provided code.  Integration with the Pytch webapp is
complicated by the fact that we get a callback if the user gives or
refuses consent, but no callback if the user just closes the pop-up.
There is therefore a separate “Cancel” operation in the modal the app
shows while waiting for the Google pop-up to invoke one of our
callbacks.  Communication regarding cancellation between the in-app
modal and the Google pop-up is handled by an <code class="docutils literal notranslate"><span class="pre">AbortController</span></code>.</p>
</section>
<section id="google-cloud-project">
<h2>Google Cloud project<a class="headerlink" href="#google-cloud-project" title="Link to this heading">¶</a></h2>
<p>The system needs to be registered with Google, saying which API
families are permitted, what sorts of user information it will want to
access, and so on.  This is set up manually through Google’s web
console.</p>
<section id="api-keys-and-other-identifiers-the-env-file">
<h3>API keys and other identifiers: the <code class="docutils literal notranslate"><span class="pre">.env</span></code> file<a class="headerlink" href="#api-keys-and-other-identifiers-the-env-file" title="Link to this heading">¶</a></h3>
<p>Various identifiers are needed when communicating with Google.  These
are stored in environment variables:</p>
<ul class="simple">
<li><p>Client ID (env.var <code class="docutils literal notranslate"><span class="pre">VITE_GOOGLE_CLIENT_ID</span></code>)</p></li>
<li><p>App ID (env.var <code class="docutils literal notranslate"><span class="pre">VITE_GOOGLE_APP_ID</span></code>)</p></li>
<li><p>API key (env.var <code class="docutils literal notranslate"><span class="pre">VITE_GOOGLE_API_KEY</span></code>)</p></li>
</ul>
<p>There is also an env.var indicating whether to use the real Google
API, or a mock for testing — see below.</p>
<p>These are all stored in a <code class="docutils literal notranslate"><span class="pre">.env</span></code> file which is not part of the repo.</p>
</section>
</section>
<section id="testing">
<h2>Testing<a class="headerlink" href="#testing" title="Link to this heading">¶</a></h2>
<p>There is a mock implementation of the two APIs.  It can be configured
to behave in certain ways so that Cypress can test the UI flow under
different conditions.</p>
</section>
<section id="flows">
<h2>Flows<a class="headerlink" href="#flows" title="Link to this heading">¶</a></h2>
<p>There are two main flows: import and export.  Each one needs the
authentication flow to have been completed first.</p>
<p>Each flow is wrapped in <code class="docutils literal notranslate"><span class="pre">doTask()</span></code>, with the following state
diagram:</p>
<figure class="align-default" id="id1">
<img alt="../../_images/google-drive-states.svg" src="../../_images/google-drive-states.svg" />
<figcaption>
<p><span class="caption-text">State-machine for Google Drive flows.</span><a class="headerlink" href="#id1" title="Link to this image">¶</a></p>
</figcaption>
</figure>
</section>
<section id="choice-of-real-vs-mock-apis">
<h2>Choice of real vs mock APIs<a class="headerlink" href="#choice-of-real-vs-mock-apis" title="Link to this heading">¶</a></h2>
<p>The real Google API objects are used for production builds and also
for the development server when a particular React environment
variable is set:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">VITE_USE_REAL_GOOGLE_DRIVE=yes</span></code></p></li>
</ul>
<p>Otherwise, the mock API objects are used, to allow Cypress testing.
This does mean that you must stop and re-start the development server
in order to switch between working with the real Google Drive and
running tests.</p>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper"><ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../user/index.html">Using the Pytch web app</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../vm/user/index.html">Writing Pytch programs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../about.html">About Pytch</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../contact.html">Contact</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../developer.html">Developer documentation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../developer/development-setup.html">Development setup</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developer/design-overview.html">Design overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../vm/developer/index.html">VM</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">Webapp</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="index.html#top-level-routes">Top-level routes</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="index.html#individual-aspects-of-design">Individual aspects of design</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../medialib/developer/index.html">Media library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developer/index.html">Website</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../build-tools/index.html">Tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../source-build.html">Source and build information</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../releases/changelog.html">Changelog</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../legal/index.html">Legal information</a></li>
</ul>
<div class="docs-home-link"><hr>
  <ul>
    <li>
      <a href="../../index.html">Pytch help home</a>
    <li>
  </ul>
</div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
  </body>
</html>